" basic.vim:    Personal Defaults Setting For Vim
" Version:      1.0.0
" Maintainer:   Sang Yang
" Reference:
"     http://spf13.com/.vimrc
"     http://tpo.pe/sensible.vim
"     https://github.com/amix/vimrc
"
" This script modify in Awesome_version by Amir Salihefendic.
" Aim to keep a personal default setting for bash/xshell.
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

" SECTION: General {{{1
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" check if the script has been loaded
if exists('g:loaded_basic') || &compatible
    finish
endif
let g:loaded_basic = 1

" set the 'cpoptions' option to its Vim default value and restore it later.
" That will allow the use of line-continuation
let s:save_cpo = &cpoptions
set cpoptions&vim

" Use Vim settings, rather than Vi settings (much better!).
" This must be first, because it changes other options as a side effect.
set nocompatible

" Enable file type detection. Also load indent files, to automatically
" do language-dependent indenting.
if has('autocmd')
    filetype plugin indent on
endif

" Switch syntax highlighting on, when the terminal has colors
if has('syntax') && !exists('g:syntax_on')
  syntax enable
endif

" Also switch on highlighting the last used search pattern.
set hlsearch

" Ignore case when searching
set ignorecase

" When searching try to be smart about cases
set smartcase

" Makes search act like search in modern browsers
set incsearch

" Print the line number in front of each line.
set number

" Show the line and column number of the cursor position for a window 
" without a status line.
set ruler

" A buffer becomes hidden when it is abandoned
set hidden

" Show (partial) command in the last line of the screen
set showcmd

" To avoid portability problems with using patterns
set magic

" SECTION: User Interface {{{1
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Sets how many lines of history VIM has to remember
if &history < 1000
    set history=1000
endif

" Maximum number of tab pages to be opened by the |-p| command line
" argument or the ":tab all" command.
if &tabpagemax < 50
    set tabpagemax=50
endif

" Set 7 lines to the cursor - when moving vertically using j/k
if !&scrolloff
    set scrolloff=7
endif

" Custom prompts caused by file messages (e.g. CTRL-G)
set shortmess=atToO

" As much as possible of the last line in a window will be displayed.
set display+=lastline

" The minimal number of screen columns to keep to the left and to the
" right of the cursor if 'nowrap' is set.
if !&sidescrolloff
    set sidescroll=10
    set sidescrolloff=5
endif

" Avoid garbled characters in Chinese language windows OS
let $LANG='en_US.UTF-8'
set langmenu=en
source $VIMRUNTIME/delmenu.vim
source $VIMRUNTIME/menu.vim

" When 'wildmode' is used, "wildmenu" mode is used where "full" 
" is specified. Complete first full match, next match, etc. 
set wildmode=full
set wildmenu

" Ignore compiled files
set wildignore=*.o,*~,*.pyc
if has("win16") || has("win32")
    set wildignore+=.git\*,.hg\*,.svn\*
else
    set wildignore+=*/.git/*,*/.hg/*,*/.svn/*,*/.DS_Store
endif

" Height of the command bar
set cmdheight=2

" Configure backspace so it acts as it should act
set backspace=eol,start,indent
set whichwrap=b,s,<,>,[,]

" No annoying sound on errors
set noerrorbells
set novisualbell
set t_vb=

" Properly disable sound on errors on MacVim
if has("gui_macvim")
    autocmd GUIEnter * set vb t_vb=
endif

" Restore the status of terminal to the front of vim
set term=xterm-256color
let &t_ti="\<Esc>[?47h"
let &t_te="\<Esc>[?47l"

" Add a bit extra margin to the left
set foldcolumn=1

" Keywords are used in searching and recognizing with many commands.
set iskeyword=a-z,A-Z,48-57,_,-,192-255

" Milliseconds that is waited for a key code or mapped key 
" sequence to complete.
if !has('nvim') && &ttimeoutlen == -1
    set ttimeout
    set ttimeoutlen=300
    set timeoutlen=500
endif

" Name of the shell to use for ! and :! commands
if &shell =~# 'fish$' 
    \ && (v:version < 704 || v:version == 704 && !has('patch276'))
    set shell=/bin/bash
endif

" When using the CTRL-A and CTRL-X, numbers that start with a zero will
" be not considered to be octal.
set nrformats-=octal

" Enable the mouse only in Normal modes
set mouse=n

" Save and restore global variables that start with an uppercase or
" lowercase letter when viminfo file is read upon startup and written
if !empty(&viminfo)
    set viminfo^=!
endif

" Changes the effect of the |:mksession| command. 
set sessionoptions=blank,buffers,curdir,folds,help,options,tabpages,winsize

" Load matchit.vim, but only if the user hasn't installed a newer version.
if !exists('g:loaded_matchit') && findfile('plugin/matchit.vim', &rtp) ==# ''
    runtime! macros/matchit.vim
endif

" With a map leader it's possible to do extra key combinations
" like <leader>w saves the current file
let mapleader = ","
let g:mapleader = ","

" SECTION: Colors and Fonts {{{1
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Allow color schemes to do bright colors without forcing bold.
if $TERM !~# '^linux\|^Eterm'
    set t_Co=256
endif

" invailded set for 'colorscheme solarized'
if v:version == 702
    let g:colors_name = "molokai"
else
    let g:colors_name = "solarized"
endif
set background=dark

" Set extra options when running in GUI mode
if has("gui_running")
    set guioptions-=T
    set guioptions-=e
    set guitablabel=%M\ %t
endif

" Mark color characters after a certain column.
cnoremap $l :<C-u>match LineNr /\%>78v.\+/

" Mark tabs not used for indentation in code.
cnoremap $t :<C-u>match TabLineFill /[^\t]\zs\t\+/

" SECTION: Files, Backups and Undo {{{1
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Set to auto read when a file is changed from the outside
set autoread

" Fast saving
nmap <leader>w :w!<cr>

" :W sudo saves the file 
" (useful for handling the permission-denied error)
command W w !sudo tee % > /dev/null

" Sets the character encoding used inside Vim.
set encoding=utf-8

" Encoding used for the terminal.
set termencoding=utf-8

" Character encodings considered when starting to edit an existing file. 
set fileencodings=ucs-bom,utf-8,utf-16,gbk,big5,gb18030,latin1

" Strings to use in 'list' mode and for the |:list| command.
set list
set listchars=tab:>\ ,trail:-,extends:>,precedes:<,nbsp:+

" Delete comment character when joining commented lines
if v:version > 703 || v:version == 703 && has("patch541")
    set formatoptions+=j
endif

" Use Unix as the standard file type
set fileformats=unix,dos,mac

" Turn backup off, since most stuff is in SVN, git et.c anyway...
set nobackup
set nowritebackup
set noswapfile

if has("autocmd")
    " When editing a file, always jump to the last known cursor position.
    autocmd BufReadPost *
        \ if line("'\"") > 1 && line("'\"") <= line("$") |
        \   exe "normal! g`\"" |
        \ endif

    " When save a file, Delete trailing white space, useful for
    " some filetypes.
    autocmd BufWritePre *.txt,*.js,*.py,*.wiki,*.sh,*.coffee 
        \ :call CleanExtraSpaces()
endif

" SECTION: Text, <Tab> and Indent {{{1
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Use the appropriate number of spaces to insert a <Tab>.
" To insert a real tab when 'expandtab' is on, use CTRL-V<Tab>.
set expandtab

" When on, a <Tab> in front of a line inserts blanks according to 
" 'shiftwidth'. When off, according to 'tabstop' or 'softtabstop'.
set smarttab

" 1 tab == 4 spaces
set shiftwidth=4
set tabstop=4
set softtabstop=4

" Linebreak on 500 characters。When 'wrap' on, lines longer than the 
" width of the window will wrap and displaying continues on the next line.
set linebreak
set textwidth=500
set wrap

" 'autoindent' copy indent from current line when starting a new line,
" it's reset when the 'paste' option is set. 'smartindent' works for 
" C-like programs.
set autoindent
set smartindent

" SECTION: Normal Mode {{{1
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" toggle paste mode on and off
map <leader>pp :setlocal paste!<cr>

" open help document about the word of the cursor position
nnoremap <F1> :h <C-R><C-W><CR>

" append '<C-L>' to clear the highlighting of :set hlsearch.
if maparg('<C-L>', 'n') ==# ''
    nnoremap <C-L>
        \ :set nohlsearch<C-R>=has('diff')?'<Bar>diffupdate':''<CR><CR><C-L>
endif

" toggle hlsearch on and off
nnoremap <leader>hl :set hlsearch!<CR>

" SECTION: Insert Mode {{{1
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
if has("autocmd")
    "Insert mode omni completion with CTRL-X CTRL-O.
    autocmd FileType css set omnifunc=csscomplete#CompleteCSS
    autocmd FileType html set omnifunc=htmlcomplete#CompleteTags 
endif

" SECTION: Visual Mode {{{1
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Visual mode pressing * or # searches for the current selection
xnoremap * :<C-u>call <SID>VSetSearch()<CR>/<C-R>=@/<CR><CR>
xnoremap # :<C-u>call <SID>VSetSearch()<CR>?<C-R>=@/<CR><CR>

" Open help document about the word of the selected area
vnoremap <F1> y:h <C-R>"<CR>

" SECTION: Command-Line Mode {{{1
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Avoid the cursor keys when recalling commands from history
cnoremap <C-P> <Up>
cnoremap <C-N> <Down>

" Easy expansion of the active file directory
cnoremap <expr> %%  getcmdtype() == ':' ? expand('%:h').'/' : '%%'

function s:LexprCommand(cmd)
    lexpr execute(a:cmd)
    lopen
endfunction

command! -nargs=1 -complete=command LexprCommand
    \ call <SID>LexprCommand(<q-args>)

" SECTION: Buffers, Windows and Tab Pages {{{1
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Recommended by Tim Pop in 'unimpaired.vim'
nnoremap [b :bprevious<CR>
nnoremap ]b :bnext<CR>
nnoremap [B :bfirst<CR>
nnoremap ]B :blast<CR>

nnoremap [t :tabprevious<CR>
nnoremap ]t :tabnext<CR>
nnoremap [T :tabfirst<CR>
nnoremap ]T :tablast<CR>

" control + vim direction key to navigate windows
noremap <C-J>     <C-W>j
noremap <C-K>     <C-W>k
noremap <C-H>     <C-W>h
noremap <C-L>     <C-W>l

" Let 'tl' toggle between this and the last accessed tab page
let g:lasttab = 1
nmap <Leader>tl :exe "tabn ".g:lasttab<CR>
if has("autocmd")
    autocmd TabLeave * let g:lasttab = tabpagenr()
endif

" Opens a new tab with the current buffer's path
" Super useful when editing files in the same directory
map <leader>te :tabedit <c-r>=expand("%:p:h")<cr>/

" Specify the behavior when switching between buffers 
try
    set switchbuf=useopen,usetab,newtab
    set showtabline=2
catch
endtry

" Convenient command to see the difference between the current buffer and the
" file it was loaded from, thus the changes you made.
" Only define it when not defined already.
if !exists(":DiffOrig")
command DiffOrig vert new | set bt=nofile | r ++edit # | 0d_ | diffthis
    \ | wincmd p | diffthis
endif

" SECTION: Patterns, Search and Substitution {{{1
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Count the matches for the current pattern.
map <leader>nb :<C-u>%s///gn<CR>

" SECTION: Status Line {{{1
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Always show the status line
set laststatus=2

" Format the status line
set statusline=\ %{&paste?'-PASTE-\ ':''}[%n]
set statusline+=\ %<%F%m%r%w
set statusline+=\ \ %{&fileformat}%Y
    \,%{&fileencoding!=''?&fileencoding:&encoding}%{&bomb?'(BOM)':''}
    \,%{&spelllang},%b,%B%{&hlsearch?',H':''}
set statusline+=\ \ %{CwdDirectory()}
set statusline+=\ \ L:%l/%L
set statusline+=\ C:%c-%v
set statusline+=\ %P
set statusline+=\ 

" SECTION: Spell Checking {{{1
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Pressing ,ss will toggle and untoggle spell checking
map <leader>ss :setlocal spell!<cr>

" Shortcuts using <leader>
map <leader>sn ]s
map <leader>sp [s
map <leader>sa zg
map <leader>s? z=

" SECTION: Cscope {{{1
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
if !has("cscope")
    set csprg=/usr/local/bin/cscope
    set csto=0
    set cscopetag
    set nocsverb
    " add any database in current directory
    if filereadable("cscope.out")
        cs add cscope.out
    " else add database pointed to by environment
    elseif $CSCOPE_DB != ""
        cs add $CSCOPE_DB
    endif
    set csverb
endif

" shortcut to access :cstag.
map <C-_> :cstag <C-R>=expand("<cword>")<CR><CR>

" These mappings for Ctrl-] (right bracket) and Ctrl-\ (backslash) allow 
" you to place your cursor over the function name or C symbol and quickly 
" query cscope for any matches.
map g<C-]> :cs find 3 <C-R>=expand("<cword>")<CR><CR>
map g<C-\> :cs find 0 <C-R>=expand("<cword>")<CR><CR>

" Or you may use the following scheme, inspired by Vim/Cscope tutorial 
" from Cscope Home Page (http://cscope.sourceforge.net/): >
nmap <C-_>s :cs find s <C-R>=expand("<cword>")<CR><CR>
nmap <C-_>g :cs find g <C-R>=expand("<cword>")<CR><CR>
nmap <C-_>c :cs find c <C-R>=expand("<cword>")<CR><CR>
nmap <C-_>t :cs find t <C-R>=expand("<cword>")<CR><CR>
nmap <C-_>e :cs find e <C-R>=expand("<cword>")<CR><CR>
nmap <C-_>f :cs find f <C-R>=expand("<cfile>")<CR><CR>
nmap <C-_>i :cs find i ^<C-R>=expand("<cfile>")<CR>$<CR>
nmap <C-_>d :cs find d <C-R>=expand("<cword>")<CR><CR>
nmap <C-_>a :cs find a <C-R>=expand("<cword>")<CR><CR>

" Using 'CTRL-spacebar' then a search type makes the vim window
" split horizontally, with search result displayed in
" the new window.
nmap <C-Space>s :scs find s <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space>g :scs find g <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space>c :scs find c <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space>t :scs find t <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space>e :scs find e <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space>f :scs find f <C-R>=expand("<cfile>")<CR><CR>
nmap <C-Space>i :scs find i ^<C-R>=expand("<cfile>")<CR>$<CR>
nmap <C-Space>d :scs find d <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space>a :scs find a <C-R>=expand("<cword>")<CR><CR>

" Hitting CTRL-space *twice* before the search type does a vertical
" split instead of a horizontal one
nmap <C-Space><C-Space>s
    \:vert scs find s <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space><C-Space>g
    \:vert scs find g <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space><C-Space>c
    \:vert scs find c <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space><C-Space>t
    \:vert scs find t <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space><C-Space>e
    \:vert scs find e <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space><C-Space>i
    \:vert scs find i ^<C-R>=expand("<cfile>")<CR>$<CR>
nmap <C-Space><C-Space>d
    \:vert scs find d <C-R>=expand("<cword>")<CR><CR>
nmap <C-Space><C-Space>a
    \:vert scs find a <C-R>=expand("<cword>")<CR><CR>

" SECTION: Abbreviations {{{1
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
iabbrev xdate <C-R>=strftime("%d/%m/%y %H:%M:%S")<CR>

" SECTION: Miscellaneous {{{1
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Remove the Windows ^M - when the encodings gets messed up
noremap <Leader>m mmHmt:%s/<C-V><cr>//ge<cr>'tzt'm

" Quickly open a buffer for scribble
map <leader>q :e ~/buffer<cr>

" Quickly open a markdown buffer for scribble
map <leader>x :e ~/buffer.md<cr>

" SECTION: Helper Functions {{{1
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Delete trailing white space on save, useful for some filetypes ;)
function! CleanExtraSpaces()
    let save_cursor = getpos(".")
    let old_query = getreg('/')
    silent! %s/\s\+$//e
    call setpos('.', save_cursor)
    call setreg('/', old_query)
endfunction

" Reset the value of '@/' to selected content in visual mode
function! s:VSetSearch()
    let temp = @s
    normal! gv"sy
    let @/ = '\V' . substitute(escape(@s, '/\'), '\n', '\\n', 'g')
    let @s = temp
endfunction

" Return CWD path，the length limit in 1/6 of the width of current windows.
function! CwdDirectory()
    let cur_dir = fnamemodify(getcwd(), ":p:~")
    let cur_dir_len = strlen(cur_dir)
    let max_width = winwidth(0)/6
    if max_width >= cur_dir_len
        return cur_dir
    else
        return '<' . strpart(cur_dir, cur_dir_len - max_width)
endfunction

" Restore 'cpoptions' option from Vim default value to previous value
let &cpoptions = s:save_cpo
unlet s:save_cpo

" vim: set sw=4 ts=4 sts=4 et tw=78 foldmethod=marker:
